package com.verify.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.verify.data.domain.*;
import com.verify.data.excel.*;
import com.verify.emun.*;
import com.verify.listener.*;
import com.verify.map.Vo2Entity;
import com.verify.repository.*;
import com.verify.util.R;
import com.verify.func.AddListValidationHandingFunction;
import com.verify.util.VerifyUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Transactional
@Service
public class ExcelVerifyServiceImpl implements ExcelVerifyService {
    private final SecondaryUnitRepository secondaryUnitRepository;
    private final ExcelUnitRepository excelUnitRepository;
    private final ExcelPersonnelRepository excelPersonnelRepository;
    private final JobTypeRepository jobTypeRepository;
    private final JobLevelRepository jobLevelRepository;
    private final PositionDictRepository positionDictRepository;
    private final DeterminePostRepository determinePostRepository;
    private final PersonInfoRepository personInfoRepository;
    private final PersonUpRepository personUpRepository;
    private final PersonDownRepository personDownRepository;
    private final AreaEntityRepository areaRepository;
    private final Vo2Entity ve2Entity;

    //行政机构校验
    public R verifyTable1(File file, Map<String, String> params) {

        List<ExcelTable1> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable1.class, new ExcelListenerTable1(table))
                .sheet("行政域组织（按关系）采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable1 t1 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyCode(t1, warnFunc, errorFunc);
            verifyName(t1, warnFunc, errorFunc);
            verifyParentCode(t1, warnFunc, errorFunc);
            verifyUnifiedSocialCreditCode(t1, warnFunc, errorFunc);
            verifyInstitutionType(t1, warnFunc, errorFunc);
            verifyInstitutionNature(t1, warnFunc, errorFunc);

            verifySoft(t1, warnFunc, errorFunc);
            i++;
        }
        if (!table.isEmpty() && error.isEmpty()) {
            List<ExcelUnit> excelUnits = excelUnitRepository.listByInCode(table.stream().map(ExcelTable1::getCode).collect(Collectors.toList()));
            if (!excelUnits.isEmpty()) {
                excelUnitRepository.removeByIds(excelUnits.stream().map(ExcelUnit::getId).collect(Collectors.toList()));
            }
            excelUnitRepository.saveBatch(ve2Entity.listToExcelUnits(table));
        }
        return R.ok().put("warn", warn).put("error", error);
    }

    private void verifySoft(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t1.getSortInfo())) {
            return;
        }
        VerifyUtil.verify(!t1.getSortInfo().matches("\\d+"), () -> "排序号必须为数字", errorFunc);
    }

    private void verifyInstitutionNature(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t1.getInstitutionNature())) {
            return;
        }

        VerifyUtil.verify(!ORG_YJWY_2021.contains(t1.getInstitutionNature()), () -> "字典中不包含机构性质", errorFunc);
    }

    private void verifyInstitutionType(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t1.getInstitutionType())) {
            return;
        }

        VerifyUtil.verify(!PG.contains(t1.getInstitutionType()), () -> "字典中不包含机构类别" + t1.getInstitutionType(), errorFunc);
    }

    private void verifyUnifiedSocialCreditCode(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t1.getUnifiedSocialCreditCode(), () -> "统一社会信用代码不能为空", errorFunc);
    }

    private void verifyParentCode(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t1.getParentOrgCode(), () -> "上级组织编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t1.getParentOrgCode())) {
            return;
        }
        //上级组织编码长度必须等于4
        VerifyUtil.verify(t1.getParentOrgCode().length() != 4, () -> "上级组织编码长度必须为4", errorFunc);
        if (t1.getParentOrgCode().length() != 4) {
            return;
        }

        if (StrUtil.isNotEmpty(t1.getCode()) && t1.getCode().length() == 4) {
            //如果当前组织为二级组织,上级组织必须为中国船舶AAAA
            SecondaryUnit secUnit = secondaryUnitRepository.getByCode(t1.getCode());
            VerifyUtil.verify(secUnit != null && !Objects.equals(t1.getParentOrgCode(), "AAAA"), () -> "二级单位上级组织编码必须为AAAA", errorFunc);
            //上级编码和当前级上级编码前两位必须一致
            VerifyUtil.verify(secUnit == null && !t1.getCode().substring(0, 2).equals(t1.getParentOrgCode().substring(0, 2)), () -> "上级组织编码和当前组织编码前两位不一致", errorFunc);
        }

        //如果上级组织为二级单位,判断名称是否相同
        SecondaryUnit parent = secondaryUnitRepository.getByCode(t1.getParentOrgCode());
        if (parent != null && StrUtil.isNotEmpty(t1.getParentOrgName())) {
            VerifyUtil.verify(!parent.getCompanyName().equals(t1.getParentOrgName()), () -> "上级组织名称和当前组织名称不一致", warnFunc);
        }
    }

    private void verifyName(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t1.getOrgName(), () -> "组织名称不能为空", errorFunc);
        if (StrUtil.isEmpty(t1.getOrgName())) {
            return;
        }

    }

    private void verifyCode(ExcelTable1 t1, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        //组织编码不能为空
        VerifyUtil.isEmpty(t1.getCode(), () -> "组织编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t1.getCode())) {
            return;
        }

        //编码不为四位
        VerifyUtil.verify(t1.getCode().length() != 4, () -> "组织编码长度不为4", errorFunc);
        if (t1.getCode().length() != 4) {
            return;
        }

        //当前组织编码是否为二级组织编码,但名称不匹配
        SecondaryUnit secUnit = secondaryUnitRepository.getByCode(t1.getCode());
        VerifyUtil.verify(StrUtil.isNotEmpty(t1.getOrgName()) && secUnit != null && !Objects.equals(secUnit.getCompanyName(), t1.getOrgName()), () -> "组织编码和二级组织" + secUnit.getCompanyName() + "一致,名称不一致", warnFunc);

        //如果不为二级组织,需要确认二级组织是否正确
        if (secUnit == null) {
            SecondaryUnit secondaryUnit = secondaryUnitRepository.getByChildCode(t1.getCode());
            VerifyUtil.verify(secondaryUnit == null, () -> "前置编号为" + t1.getCode().substring(0, 2) + "二级单位组织编码未找到", errorFunc);
            VerifyUtil.verify(secondaryUnit != null, () -> "对应二级单位是否为：" + secondaryUnit.getCompanyName(), warnFunc);
        }
        //当前编码是否与导入的其他组织重复
        ExcelUnit noNameUnit = excelUnitRepository.getByCodeAndNoName(t1.getCode(), t1.getOrgName());
        VerifyUtil.verify(noNameUnit != null, () -> "当前编码与导入的其他组织" + noNameUnit.getOrgName() + "重复", errorFunc);
    }

    @Override
    public R verifyTable2(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable2> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable2.class, new ExcelListenerTable2(table))
                .sheet("人事域机构（按关系）采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable2 t2 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyOrgCode(t2, orgCode, table, warnFunc, errorFunc);
            verifyOrgName(t2, warnFunc, errorFunc);
            verifyParentCode(t2, table, warnFunc, errorFunc);
            verifyInstitutionType(t2, warnFunc, errorFunc);
            verifyInstitutionNature(t2, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<ExcelPersonnel> excelPersonnel = excelPersonnelRepository.listByLikeCode(table.get(0).getCode().substring(0, 4));
            if (!excelPersonnel.isEmpty()) {
                excelPersonnelRepository.removeByIds(excelPersonnel.stream().map(ExcelPersonnel::getId).collect(Collectors.toList()));
            }
            List<ExcelPersonnel> excelPerson = ve2Entity.listToExcelPersonnel(table);
            for (ExcelPersonnel person : excelPerson) {
                person.setOrgCode(orgCode);
            }
            excelPersonnelRepository.saveBatch(excelPerson);
        }
        return R.ok().put("warn", warn).put("error", error);
    }

    @Override
    public R verifyTable3(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable3> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable3.class, new ExcelListenerTable3(table))
                .sheet("公司岗位类型采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable3 t3 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyPositionTypeCode(t3, table, warnFunc, errorFunc);
            verifyPositionTypeName(t3, warnFunc, errorFunc);
            verifyRelatedStandardPositionType(t3, table, warnFunc, errorFunc);
            verifySort(t3, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<JobType> jobs = jobTypeRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                jobTypeRepository.removeByIds(jobs.stream().map(JobType::getId).collect(Collectors.toList()));
            }
            List<JobType> jobTypes = ve2Entity.listToJobType(table);
            for (JobType job : jobTypes) {
                job.setOrgCode(orgCode);
            }
            jobTypeRepository.saveBatch(jobTypes);
        }
        return R.ok().put("warn", warn).put("error", error);
    }

    @Override
    public R verifyTable4(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable4> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable4.class, new ExcelListenerTable4(table))
                .sheet("公司岗位层级采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable4 t4 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyPositionTypeName(t4, orgCode, warnFunc, errorFunc);
            verifyPositionLevelName(t4, warnFunc, errorFunc);
            verifyRelatedStandardPositionLevelName(t4, orgCode, table, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<JobLevel> jobs = jobLevelRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                jobLevelRepository.removeByIds(jobs.stream().map(JobLevel::getId).collect(Collectors.toList()));
            }
            List<JobLevel> jobLevels = ve2Entity.listToJobLevel(table);
            for (JobLevel job : jobLevels) {
                job.setOrgCode(orgCode);
            }
            jobLevelRepository.saveBatch(jobLevels);
        }
        return R.ok().put("warn", warn).put("error", error);
    }

    @Override
    public R verifyTable5(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable5> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable5.class, new ExcelListenerTable5(table))
                .sheet("公司岗位字典采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable5 t5 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyCompanyPositionTypeName(t5, orgCode, warnFunc, errorFunc);
            verifyCompanyPositionDictionaryName(t5, orgCode, warnFunc, errorFunc);
            verifyCodeAndName(t5, orgCode, warnFunc, errorFunc);
            verifySort(t5, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<PositionDict> jobs = positionDictRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                positionDictRepository.removeByIds(jobs.stream().map(PositionDict::getId).collect(Collectors.toList()));
            }
            List<PositionDict> jobLevels = ve2Entity.listToDic(table);
            for (PositionDict job : jobLevels) {
                job.setOrgCode(orgCode);
            }
            positionDictRepository.saveBatch(jobLevels);
        }
        return R.ok().put("warn", warn).put("error", error);
    }

    @Override
    public R verifyTable6(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable6> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable6.class, new ExcelListenerTable6(table))
                .sheet("定岗信息采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable6 t6 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyPositionOrgFullName(t6, orgCode, warnFunc, errorFunc);
            verifyTypeDic(t6, orgCode, warnFunc, errorFunc);
            verifyPositionName(t6, orgCode, warnFunc, errorFunc);
            verifyLevel(t6, orgCode, warnFunc, errorFunc);
            verifyPositionGroup(t6, orgCode, warnFunc, errorFunc);
            verifyManagementLevel(t6, orgCode, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<DeterminePost> jobs = determinePostRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                determinePostRepository.removeByIds(jobs.stream().map(DeterminePost::getId).collect(Collectors.toList()));
            }
            List<DeterminePost> jobLevels = ve2Entity.listToPost(table);
            for (DeterminePost job : jobLevels) {
                job.setOrgCode(orgCode);
            }
            determinePostRepository.saveBatch(jobLevels);
        }

        return R.ok().put("warn", warn).put("error", error);
    }

    public static boolean isValidDate(String date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        try {
            LocalDate.parse(date, formatter);
            return true;
        } catch (DateTimeParseException e) {
            return false;
        }
    }

    @Override
    public R verifyTable7(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable7> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable7.class, new ExcelListenerTable7(table))
                .sheet("基本信息采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable7 t7 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);
            //工号 todo 生成即可,暂不校验

            verifyName(t7, orgCode, warnFunc, errorFunc);

            verifyPersonType(t7, orgCode, warnFunc, errorFunc);

            verifyPersonSource(t7, orgCode, warnFunc, errorFunc);

            verifyIdType(t7, orgCode, warnFunc, errorFunc);

            verifyIdNumber(t7, orgCode, warnFunc, errorFunc);

            verifyGender(t7, orgCode, warnFunc, errorFunc);

            verifyBirthday(t7, orgCode, warnFunc, errorFunc);

            verifyEthnicity(t7, orgCode, warnFunc, errorFunc);

            verifyNationality(t7, orgCode, warnFunc, errorFunc);

            verifyNativePlace(t7, orgCode, warnFunc, errorFunc);

            verifyBirthPlace(t7, orgCode, warnFunc, errorFunc);

            verifyHouseholdType(t7, orgCode, warnFunc, errorFunc);

            verifyHouseholdLocation(t7, orgCode, warnFunc, errorFunc);

            verifyMaritalStatus(t7, orgCode, warnFunc, errorFunc);

            verifyPoliticalStatus(t7, orgCode, warnFunc, errorFunc);

            verifyPartyJoinDate(t7, orgCode, warnFunc, errorFunc);

            verifyJoinDate(t7, orgCode, warnFunc, errorFunc);

            verifyIsVeteran(t7, orgCode, warnFunc, errorFunc);

            verifyIsEducation(t7, orgCode, warnFunc, errorFunc);

            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<PersonInfo> jobs = personInfoRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                personInfoRepository.removeByIds(jobs.stream().map(PersonInfo::getId).collect(Collectors.toList()));
            }
            List<PersonInfo> jobLevels = ve2Entity.listToInfo(table);
            for (PersonInfo job : jobLevels) {
                job.setOrgCode(orgCode);
            }
            personInfoRepository.saveBatch(jobLevels);
        }

        return R.ok().put("warn", warn).put("error", error);
    }

    private void verifyIsEducation(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isNotEmpty(t7.getEducation())) {
            VerifyUtil.verify(!T4658.contains(t7.getEducation()), () -> "学历填写不正确", errorFunc);
        }

        VerifyUtil.verify(StrUtil.isNotEmpty(t7.getIsFullTime()) && !UT.YES.getName().equals(t7.getIsFullTime()), () -> "填写全日制最高学历", errorFunc);

        VerifyUtil.verify(StrUtil.isNotEmpty(t7.getIsHighestEducation()) && !UT.contains(t7.getIsHighestEducation()), () -> "是否最高学历填写不正确", errorFunc);
    }

    private void verifyIsVeteran(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isNotEmpty(t7.getIsVeteran())) {
            VerifyUtil.verify(!UT.contains(t7.getIsVeteran()), () -> "是否复转军人填写不正确", errorFunc);
        }
    }

    private void verifyJoinDate(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {

        if (StrUtil.isNotEmpty(t7.getWorkStartDate())) {
            VerifyUtil.verify(!isValidDate(t7.getWorkStartDate()), () -> "参加工作日期格式不正确", errorFunc);
        }
        if (StrUtil.isNotEmpty(t7.getGroupJoinDate())) {
            VerifyUtil.verify(!isValidDate(t7.getGroupJoinDate()), () -> "进入集团日期格式不正确", errorFunc);
        }
        VerifyUtil.isEmpty(t7.getCompanyJoinDate(), () -> "进入集团日期不能为空", errorFunc);
        if (StrUtil.isNotEmpty(t7.getCompanyJoinDate())) {
            VerifyUtil.verify(!isValidDate(t7.getCompanyJoinDate()), () -> "进入公司日期格式不正确", errorFunc);
        }

        VerifyUtil.isEmpty(t7.getSalaryStartDate(), () -> "开始起薪日期不能为空", errorFunc);
        if (StrUtil.isNotEmpty(t7.getSalaryStartDate())) {
            VerifyUtil.verify(!isValidDate(t7.getSalaryStartDate()), () -> "开始起薪日期格式不正确", errorFunc);
        }
    }

    private void verifyPartyJoinDate(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.verify(StrUtil.isEmpty(t7.getPartyJoinDate()) && StrUtil.isNotEmpty(t7.getPoliticalStatus()) && !GB4762.BAO_STEEL_ETHNIC_ASSOCIATION.MASSES.getName().equals(t7.getPoliticalStatus()), () -> "参加党派日期不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getPartyJoinDate())) {
            return;
        }
        VerifyUtil.verify(!isValidDate(t7.getPartyJoinDate()), () -> "参加党派日期格式不正确", errorFunc);
    }

    private void verifyPoliticalStatus(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getPoliticalStatus(), () -> "政治面貌不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getPoliticalStatus())) {
            return;
        }
        VerifyUtil.verify(!GB4762.contains(t7.getPoliticalStatus()), () -> "政治面貌只能为群众、党员、预备党员、其他", errorFunc);
    }

    private void verifyMaritalStatus(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getMaritalStatus())) {
            return;
        }
        VerifyUtil.verify(!T2261_2.contains(t7.getMaritalStatus()), () -> "婚姻状况只能为未婚、离婚、丧偶、已婚", errorFunc);
    }

    private void verifyHouseholdLocation(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getHouseholdLocation())) {
            return;
        }

        VerifyUtil.verify(areaRepository.getByName(t7.getHouseholdLocation()) == null, () -> "字典中不包含该户口所在地", errorFunc);
    }

    private void verifyHouseholdType(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getHouseholdType())) {
            return;
        }
        VerifyUtil.verify(!B2.contains(t7.getHouseholdType()), () -> "户口性质只能为非农业户口、农业户口、其他", errorFunc);
    }

    private void verifyBirthPlace(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getBirthPlace())) {
            return;
        }
        VerifyUtil.verify(areaRepository.getByName(t7.getBirthPlace()) == null, () -> "字典中不包含该出生地", errorFunc);
    }

    private void verifyNativePlace(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getNativePlace())) {
            return;
        }
        VerifyUtil.verify(areaRepository.getByName(t7.getNativePlace()) == null, () -> "字典中不包含该籍贯", errorFunc);
    }

    private void verifyNationality(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getNationality(), () -> "国籍不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getNationality())) {
            return;
        }
        VerifyUtil.verify(!AREA_NA.contains(t7.getNationality()), () -> "国籍字典中不包含该值", errorFunc);
    }

    private void verifyEthnicity(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getEthnicity(), () -> "民族不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getEthnicity())) {
            return;
        }
        VerifyUtil.verify(!GB3304.contains(t7.getEthnicity()), () -> "民族字典中不包含该值", errorFunc);
    }

    private void verifyBirthday(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getBirthDate())) {
            return;
        }
        VerifyUtil.verify(!isValidDate(t7.getBirthDate()), () -> "出生日期格式不正确", errorFunc);
    }

    private void verifyGender(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getGender(), () -> "性别不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getGender())) {
            return;
        }
        VerifyUtil.verify(!T2261_1.contains(t7.getGender()), () -> "性别字典中不包含该值", errorFunc);
    }

    private void verifyIdNumber(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getIdNumber(), () -> "证件号码不能为空", errorFunc);
    }

    private void verifyIdType(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getIdType(), () -> "证件类型不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getIdType())) {
            return;
        }
        VerifyUtil.verify(!KQ.contains(t7.getIdType()), () -> "证件类型字典中不包含该值", errorFunc);
    }

    private void verifyPersonSource(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t7.getPersonSource())) {
            return;
        }
        VerifyUtil.verify(!GB12405.contains(t7.getPersonSource()), () -> "人员来源字典中不包含该值", errorFunc);
    }

    private void verifyPersonType(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getPersonType(), () -> "人员类型不能为空", errorFunc);
        if (StrUtil.isEmpty(t7.getPersonType())) {
            return;
        }
        VerifyUtil.verify(!PC.contains(t7.getPersonType()), () -> "人员类型字典中不包含该值", errorFunc);
    }

    private void verifyName(ExcelTable7 t7, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t7.getName(), () -> "姓名不能为空", errorFunc);
    }

    @Override
    public R verifyTable8(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable8> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable8.class, new ExcelListenerTable8(table))
                .sheet("岗位聘用采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable8 t8 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyName(t8, orgCode, warnFunc, errorFunc);
            verifyPerson(t8, orgCode, warnFunc, errorFunc);
            verifyEmploymentPositionCode(t8, orgCode, warnFunc, errorFunc);
            verifyStaffingType(t8, orgCode, warnFunc, errorFunc);
            verifyDate(t8, orgCode, warnFunc, errorFunc);
            verifyPostGroup(t8, orgCode, warnFunc, errorFunc);
            verifyArea(t8, orgCode, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<PersonDown> jobs = personDownRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                personDownRepository.removeByIds(jobs.stream().map(PersonDown::getId).collect(Collectors.toList()));
            }
            List<PersonUp> jobLevels = ve2Entity.listToUp(table);
            for (PersonUp job : jobLevels) {
                job.setOrgCode(orgCode);
            }
            personUpRepository.saveBatch(jobLevels);
        }

        return R.ok().put("warn", warn).put("error", error);
    }

    private void verifyArea(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t8.getWorkCity())) {
            return;
        }
        VerifyUtil.verify(areaRepository.getByName(t8.getWorkCity()) == null, () -> "工作城市与机构编码不匹配", errorFunc);
    }

    private void verifyPostGroup(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t8.getPositionGroup())) {
            return;
        }
        VerifyUtil.verify(!POST_GROUP.contains(t8.getPositionGroup()), () -> "岗位族群字典中不包含该值", errorFunc);
    }

    private void verifyDate(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t8.getEmploymentDate())) {
            return;
        }
        VerifyUtil.verify(!isValidDate(t8.getEmploymentDate()), () -> "聘用日期格式不正确", errorFunc);
    }

    private void verifyStaffingType(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t8.getStaffingType(), () -> "编制类型不能为空", errorFunc);
        if (StrUtil.isEmpty(t8.getStaffingType())) {
            return;
        }
        VerifyUtil.verify(!MU2021.contains(t8.getStaffingType()), () -> "编制类型字典中不包含该值", errorFunc);
    }

    private void verifyEmploymentPositionCode(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {

        VerifyUtil.isEmpty(t8.getEmploymentPositionCode(), () -> "聘用岗位编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t8.getEmploymentPositionCode())) {
            return;
        }

        DeterminePost post = determinePostRepository.getByName(t8.getEmploymentPositionCode(), orgCode);
        VerifyUtil.verify(post == null, () -> "该编码上填写的岗位名称不存在", errorFunc);
    }

    private void verifyPerson(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t8.getEmploymentOrgCode(), () -> "聘用机构编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t8.getEmploymentOrgCode())) {
            return;
        }
        ExcelPersonnel personnel = excelPersonnelRepository.getByCode(t8.getEmploymentOrgCode(), orgCode);

        VerifyUtil.verify(personnel == null, () -> "该编码在当前机构下不存在", errorFunc);

        VerifyUtil.verify(personnel != null && StrUtil.isNotEmpty(t8.getEmploymentOrgFullName()) && !personnel.getOrgName().equals(t8.getEmploymentOrgFullName()), () -> "机构全称与编码不匹配", errorFunc);

    }

    private void verifyName(ExcelTable8 t8, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t8.getName(), () -> "姓名不能为空", errorFunc);
        if (StrUtil.isEmpty(t8.getName())) {
            return;
        }
        List<PersonInfo> persons = personInfoRepository.listByName(t8.getName(), orgCode);
        VerifyUtil.operation(persons.isEmpty(), () -> "该姓名在当前机构下不存在", errorFunc);
    }

    @Override
    public R verifyTable9(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<ExcelTable9> table = new ArrayList<>();
        EasyExcel.read(file, ExcelTable9.class, new ExcelListenerTable9(table))
                .sheet("员工离岗采集表").headRowNumber(7).doRead();

        List<String> warn = new ArrayList<>();
        List<String> error = new ArrayList<>();

        int i = 1;
        for (ExcelTable9 t9 : table) {
            AddListValidationHandingFunction warnFunc = new AddListValidationHandingFunction(warn, i);
            AddListValidationHandingFunction errorFunc = new AddListValidationHandingFunction(error, i);

            verifyName(t9, orgCode, warnFunc, errorFunc);
            //离岗管理机构编码
            verifyOffDutyOrgCode(t9, orgCode, warnFunc, errorFunc);

            verifyOffDuty(t9, orgCode, warnFunc, errorFunc);
            i++;
        }

        if (!table.isEmpty() && error.isEmpty()) {
            List<PersonDown> jobs = personDownRepository.listByOrgCode(orgCode);
            if (!jobs.isEmpty()) {
                personDownRepository.removeByIds(jobs.stream().map(PersonDown::getId).collect(Collectors.toList()));
            }
            List<PersonDown> jobLevels = ve2Entity.listToDown(table);
            for (PersonDown job : jobLevels) {
                job.setOrgCode(orgCode);
            }
            personDownRepository.saveBatch(jobLevels);
        }

        return R.ok().put("warn", warn).put("error", error);
    }

    private void verifyOffDuty(ExcelTable9 t9, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {

        VerifyUtil.isEmpty(t9.getOffDutyType(), () -> "离岗类型不能为空", errorFunc);
        VerifyUtil.isEmpty(t9.getOffDutyDate(), () -> "离岗类型不能为空", errorFunc);
        VerifyUtil.verify(StrUtil.isNotEmpty(t9.getOffDutyType()) && !PO.contains(t9.getOffDutyType()), () -> "离岗类型字典中不包含该值", errorFunc);

        VerifyUtil.verify(StrUtil.isNotEmpty(t9.getOffDutyDate()) && !isValidDate(t9.getOffDutyDate()), () -> "离岗日期格式不正确", errorFunc);
    }

    private void verifyOffDutyOrgCode(ExcelTable9 t9, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t9.getOffDutyOrgCode(), () -> "离岗管理机构编码不能为空", errorFunc);

        if (StrUtil.isNotEmpty(t9.getOffDutyOrgCode())) {
            ExcelPersonnel personnel = excelPersonnelRepository.getByCode(t9.getOffDutyOrgCode(), orgCode);
            VerifyUtil.verify(personnel == null, () -> "离岗管理机构编码不存在", errorFunc);

            VerifyUtil.verify(personnel != null && !personnel.getOrgName().equals(t9.getOffDutyOrgFullName()), () -> "机构全称与表2不匹配", errorFunc);
        }
    }

    private void verifyName(ExcelTable9 t9, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t9.getName(), () -> "姓名不能为空", errorFunc);
        if (StrUtil.isEmpty(t9.getName())) {
            return;
        }
        VerifyUtil.verify(personInfoRepository.listByName(t9.getName(), orgCode).isEmpty(), () -> "该人员表7不存在", errorFunc);
    }

    @Override
    public R areaInit(File file, Map<String, String> params) {
        String orgCode = params.get("orgCode");

        List<AREA> table = new ArrayList<>();
        EasyExcel.read(file, AREA.class, new ExcelListenerAreaEntity(table))
                .sheet("地区信息库").headRowNumber(1).doRead();


        areaRepository.saveBatch(ve2Entity.listToArea(table));

        return R.ok();
    }

    private void verifyManagementLevel(ExcelTable6 t6, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t6.getPositionType())) {
            return;
        }
        JobType jobType = jobTypeRepository.getByNameAndOrgCode(t6.getPositionType(), orgCode);
        if (jobType != null && STANDARDT_POST_TYPE.MANAGEMENT.getName().equals(jobType.getRelatedStandardPositionType())) {
            VerifyUtil.verify(StrUtil.isNotEmpty(t6.getManagementLevel()) && !DG_2021.contains(t6.getManagementLevel()), () -> "管理岗位层级字典中不包含该值", errorFunc);
        }
    }

    private void verifyPositionGroup(ExcelTable6 t6, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t6.getPositionGroup(), () -> "岗位族群为空", errorFunc);
        VerifyUtil.verify(StrUtil.isNotEmpty(t6.getPositionGroup()) && !POST_GROUP.contains(t6.getPositionGroup()), () -> "字典中不包含该岗位族群", errorFunc);
    }

    private void verifyLevel(ExcelTable6 t6, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t6.getPositionLevelType(), () -> "岗位层级类型为空", errorFunc);
        VerifyUtil.isEmpty(t6.getPositionLevelUpperLimit(), () -> "岗位层级上限为空", errorFunc);
        VerifyUtil.isEmpty(t6.getPositionLevelLowerLimit(), () -> "岗位层级下限为空", errorFunc);

        VerifyUtil.verify(StrUtil.isNotEmpty(t6.getPositionLevelType()) && !POST_LEVEL_TYPE.contains(t6.getPositionLevelType()), () -> "岗位层级类型不合法", errorFunc);

        if (StrUtil.isNotEmpty(t6.getPositionLevelLowerLimit()) && StrUtil.isNotEmpty(t6.getPositionLevelUpperLimit()) && POST_LEVEL_TYPE.SINGLE.getName().equals(t6.getPositionLevelType())) {
            VerifyUtil.verify(!t6.getPositionLevelLowerLimit().equals(t6.getPositionLevelUpperLimit()), () -> "单一层级,岗位层级上限和下限需要相等", errorFunc);
        }

        if (StrUtil.isNotEmpty(t6.getPositionLevelLowerLimit()) && StrUtil.isNotEmpty(t6.getPositionLevelUpperLimit()) && POST_LEVEL_TYPE.RANGE.getName().equals(t6.getPositionLevelType())) {
            VerifyUtil.verify(t6.getPositionLevelLowerLimit().equals(t6.getPositionLevelUpperLimit()), () -> "范围层级,岗位层级上限和下限需要不相等", errorFunc);
        }
        List<JobLevel> jobLevels = null;
        if (StrUtil.isNotEmpty(t6.getPositionType())) {
            jobLevels = jobLevelRepository.listByType(t6.getPositionType(), orgCode);
            VerifyUtil.verify(jobLevels.isEmpty(), () -> "未在表4中根据" + t6.getPositionType() + "找到关联的岗位层级", errorFunc);
        }

        if (StrUtil.isNotEmpty(t6.getPositionLevelLowerLimit()) && jobLevels != null) {
            //todo 层级上下限顺序是否对就不校验了,写起来好烦
            List<String> levelNames = jobLevels.stream().map(JobLevel::getPositionLevelName).collect(Collectors.toList());
            VerifyUtil.verify(!levelNames.isEmpty() && !levelNames.contains(t6.getPositionLevelLowerLimit()), () -> "未在表4匹配到对应的岗位层级下限", errorFunc);
        }

        if (StrUtil.isNotEmpty(t6.getPositionLevelUpperLimit()) && jobLevels != null) {
            List<String> levelNames = jobLevels.stream().map(JobLevel::getPositionLevelName).collect(Collectors.toList());
            VerifyUtil.verify(!levelNames.isEmpty() && !levelNames.contains(t6.getPositionLevelUpperLimit()), () -> "未在表4匹配到对应的岗位层级上限", errorFunc);
        }

    }

    private void verifyPositionName(ExcelTable6 t6, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t6.getPositionName(), () -> "定岗岗位名称为空", errorFunc);
    }

    private void verifyTypeDic(ExcelTable6 t6, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        //todo 岗位类型和岗位字典的岗位类型要完全对应吗
        VerifyUtil.isEmpty(t6.getPositionType(), () -> "岗位类型为空", errorFunc);
        VerifyUtil.isEmpty(t6.getPositionDictCode(), () -> "岗位字典编码为空", warnFunc);
        VerifyUtil.isEmpty(t6.getPositionDictName(), () -> "岗位字典名称为空", warnFunc);

        if (StrUtil.isNotEmpty(t6.getPositionType())) {
            List<PositionDict> dictType = positionDictRepository.listByType(t6.getPositionType(), orgCode);
            VerifyUtil.verify(dictType.isEmpty(), () -> "未在表5中根据" + t6.getPositionType() + "找到关联的岗位类型", errorFunc);
        }

        if (StrUtil.isNotEmpty(t6.getPositionDictName()) && StrUtil.isNotEmpty(t6.getPositionType())) {
            PositionDict dict = positionDictRepository.getByName(t6.getPositionDictName(), t6.getPositionType(), orgCode);
            VerifyUtil.verify(dict == null, () -> "岗位字典名称（关联）在表5中不存在", errorFunc);

            //todo 岗位字典编码需要人工填充,该字段为系统自动生成,暂无好办法
            //todo 岗位类型是否和表五保持一致
            VerifyUtil.verify(dict != null && StrUtil.isNotEmpty(t6.getPositionType()) && !dict.getCompanyPositionTypeName().equals(t6.getPositionType()), () -> "岗位类型名称与表5中岗位类型名称不一致", errorFunc);
        }
    }

    private void verifyPositionOrgFullName(ExcelTable6 t6, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        ExcelPersonnel personnel = excelPersonnelRepository.getByCode(t6.getPositionOrgCode());
        VerifyUtil.verify(personnel == null, () -> "定岗机构编码不存在", errorFunc);
        if (personnel == null) {
            return;
        }
        VerifyUtil.isEmpty(t6.getPositionOrgFullName(), () -> "定岗机构全称为空", warnFunc);
        VerifyUtil.verify(StrUtil.isNotEmpty(t6.getPositionOrgFullName()) && !personnel.getOrgName().equals(t6.getPositionOrgFullName()), () -> "定岗机构全称与表2中机构全称不一致", errorFunc);
    }

    private void verifySort(ExcelTable5 t5, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t5.getOrderInfo())) {
            return;
        }
        VerifyUtil.verify(!t5.getOrderInfo().matches("\\d+"), () -> "排序号必须为数字", errorFunc);
    }

    private void verifyCodeAndName(ExcelTable5 t5, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t5.getStandardPositionDictionaryCode(), () -> "岗位编码不能为空", warnFunc);
        if (StrUtil.isEmpty(t5.getStandardPositionDictionaryCode())) {
            return;
        }

        STANDARDT_POST_DICT code = STANDARDT_POST_DICT.getByCode(t5.getStandardPositionDictionaryCode());
        VerifyUtil.verify(code == null, () -> "岗位编码" + t5.getStandardPositionDictionaryCode() + "不存在", errorFunc);
        if (code == null){
            return;
        }
        VerifyUtil.verify(StrUtil.isNotEmpty(t5.getStandardPositionDictionaryName()) && !code.getName().equals(t5.getStandardPositionDictionaryName()), () -> "标准岗位字典名称" + t5.getStandardPositionDictionaryName() + "与岗位编码" + t5.getStandardPositionDictionaryCode() + "不匹配", errorFunc);


        JobType jobType = jobTypeRepository.getByNameAndOrgCode(t5.getCompanyPositionTypeName(), orgCode);

        if (jobType == null) {
            return;
        }
        VerifyUtil.verify(StrUtil.isNotEmpty(jobType.getRelatedStandardPositionType()) && !jobType.getRelatedStandardPositionType().equals(code.getType()), () -> "公司岗位类型和标准岗位字段不匹配", errorFunc);
    }

    private void verifyCompanyPositionDictionaryName(ExcelTable5 t5, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {

        VerifyUtil.isEmpty(t5.getCompanyPositionDictionaryName(), () -> "标准岗位字典名称不能", errorFunc);
    }

    private void verifyCompanyPositionTypeName(ExcelTable5 t5, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t5.getCompanyPositionTypeName(), () -> "公司岗位类型名称不能为空", errorFunc);
        if (StrUtil.isEmpty(t5.getCompanyPositionTypeName())) {
            return;
        }

        JobType jobType = jobTypeRepository.getByNameAndOrgCode(t5.getCompanyPositionTypeName(), orgCode);
        VerifyUtil.verify(jobType == null, () -> "公司岗位类型名称" + t5.getCompanyPositionTypeName() + "不存在", errorFunc);
        if (jobType == null) {
            return;
        }
    }

    private void verifyRelatedStandardPositionLevelName(ExcelTable4 t4, String orgCode, List<ExcelTable4> table, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t4.getRelatedStandardPositionLevelName(), () -> "关联标准岗位层级名称不能为空", errorFunc);
        if (StrUtil.isEmpty(t4.getRelatedStandardPositionLevelName())) {
            return;
        }
        JobType jobType = jobTypeRepository.getByNameAndOrgCode(t4.getPositionTypeName(), orgCode);
        if (jobType == null) {
            return;
        }
        //VerifyUtil.verify(!STANDARDT_POST_LEVEL.isMatch(t4.getRelatedStandardPositionLevelName(), jobType.getRelatedStandardPositionType()), () -> "关联的关联标准岗位层级名称" + t4.getRelatedStandardPositionLevelName() + "不在标准类型对应下", errorFunc);
        //todo 疑问 岗位层级不是和岗位类型对应的吗
        VerifyUtil.verify(!STANDARDT_POST_LEVEL.isMatch(t4.getRelatedStandardPositionLevelName()), () -> "关联的关联标准岗位层级名称" + t4.getRelatedStandardPositionLevelName() + "不在标准类型对应下", errorFunc);
    }

    private void verifyPositionLevelName(ExcelTable4 t4, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t4.getPositionLevelName(), () -> "岗位层级名称不能为空", errorFunc);
    }

    private void verifyPositionTypeName(ExcelTable4 t4, String orgCode, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t4.getPositionTypeName(), () -> "岗位类型名称不能为空", errorFunc);
        if (StrUtil.isEmpty(t4.getPositionTypeName())) {
            return;
        }
        JobType jobType = jobTypeRepository.getByNameAndOrgCode(t4.getPositionTypeName(), orgCode);
        VerifyUtil.verify(jobType == null, () -> "关联的岗位类型名称" + t4.getPositionTypeName() + "不存在", errorFunc);
    }

    private void verifySort(ExcelTable3 t3, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t3.getOrderInfo())) {
            return;
        }
        VerifyUtil.verify(!t3.getOrderInfo().matches("\\d+"), () -> "排序号必须为数字", errorFunc);
    }

    private void verifyRelatedStandardPositionType(ExcelTable3 t3, List<ExcelTable3> table, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t3.getRelatedStandardPositionType(), () -> "关联标准岗位类型不能为空", errorFunc);
        if (StrUtil.isEmpty(t3.getRelatedStandardPositionType())) {
            return;
        }
        VerifyUtil.verify(!STANDARDT_POST_TYPE.contains(t3.getRelatedStandardPositionType()), () -> "关联标准岗位类型" + t3.getRelatedStandardPositionType() + "不存在", errorFunc);
    }

    private void verifyPositionTypeName(ExcelTable3 t3, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t3.getPositionTypeName(), () -> "岗位类型名称不能为空", errorFunc);
    }

    private void verifyPositionTypeCode(ExcelTable3 t3, List<ExcelTable3> table, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t3.getPositionTypeCode(), () -> "岗位类型编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t3.getPositionTypeCode())) {
            return;
        }
        VerifyUtil.verify(!t3.getPositionTypeCode().matches("^[A-Z]+$"), () -> "岗位类型编码只能大写字母", errorFunc);
    }

    private void verifyInstitutionNature(ExcelTable2 t2, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        if (StrUtil.isEmpty(t2.getInstitutionNature())) {
            return;
        }
        VerifyUtil.verify(!FM.contains(t2.getInstitutionNature()), () -> "机构性质" + t2.getInstitutionNature() + "不存在", errorFunc);
    }

    private void verifyInstitutionType(ExcelTable2 t2, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t2.getInstitutionType(), () -> "机构类型不能为空", errorFunc);
        if (StrUtil.isEmpty(t2.getInstitutionType())) {
            return;
        }
        ORG_TYPE ORGTYPE = ORG_TYPE.getByName(t2.getInstitutionType());
        VerifyUtil.verify(ORGTYPE == null, () -> "机构类型" + t2.getInstitutionType() + "不存在", errorFunc);
        if (ORGTYPE == null) {
            return;
        }
        VerifyUtil.verify(StrUtil.isNotEmpty(t2.getCode()) && !ORG_TYPE.containLength(ORGTYPE, t2.getCode().length()), () -> "机构类型" + t2.getCode() + "编码长度应该为" + ORGTYPE.getLength(), errorFunc);

    }

    private void verifyParentCode(ExcelTable2 t2, List<ExcelTable2> table, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t2.getParentOrgCode(), () -> "上级机构编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t2.getParentOrgCode())) {
            return;
        }
        List<String> orgCode = table.stream().map(ExcelTable2::getCode).filter(StrUtil::isNotEmpty).filter(t -> t.length() >= 4).map(s -> s.substring(0, 4)).distinct().collect(Collectors.toList());

        VerifyUtil.verify(StrUtil.isNotEmpty(t2.getCode()) && !t2.getCode().substring(0, 4).equals(t2.getParentOrgCode().substring(0, 4)), () -> "上级机构编码前四位和机构编码前四位不一致", errorFunc);
        VerifyUtil.verify(orgCode.size() == 1 && t2.getParentOrgCode().length() == 6 && !t2.getParentOrgCode().equals(orgCode.get(0) + "00"), () -> "上级机构编码为六位时,应该为总部编码:" + orgCode.get(0) + "00", errorFunc);
        List<String> allCode = table.stream().map(ExcelTable2::getCode).filter(StrUtil::isNotEmpty).filter(t -> t.length() >= 4).collect(Collectors.toList());
        VerifyUtil.verify(t2.getParentOrgCode().length() != 6 && !allCode.contains(t2.getParentOrgCode()), () -> "上级机构编码不存在", errorFunc);
    }

    private void verifyOrgName(ExcelTable2 t2, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t2.getOrgName(), () -> "机构名称不能为空", errorFunc);
    }

    private void verifyOrgCode(ExcelTable2 t2, String fOrgCode, List<ExcelTable2> table, AddListValidationHandingFunction warnFunc, AddListValidationHandingFunction errorFunc) {
        VerifyUtil.isEmpty(t2.getCode(), () -> "机构编码不能为空", errorFunc);
        if (StrUtil.isEmpty(t2.getCode())) {
            return;
        }
        VerifyUtil.verify(t2.getCode().length() > 4 && !t2.getCode().substring(0, 4).equals(fOrgCode), () -> "上级机构编码前四位和所校验公司编码前四位不一致", errorFunc);

        //判断组织编码前四位是否都是同一个公司的
        if (t2.equals(table.get(0))) {
            List<String> orgCode = table.stream().map(ExcelTable2::getCode).filter(StrUtil::isNotEmpty).filter(t -> t.length() >= 4).map(s -> s.substring(0, 4)).distinct().collect(Collectors.toList());
            VerifyUtil.verify(orgCode.size() != 1, () -> "检查机构编码前缀是否一致", errorFunc);

            if (orgCode.size() == 1 && orgCode.get(0).length() > 4) {
                ExcelUnit excelUnit = excelUnitRepository.getByCode(orgCode.get(0).substring(0, 4));
                VerifyUtil.verify(excelUnit == null, () -> "根据编码[" + t2.getCode() + "]司库中未找到对应的公司", errorFunc);
            }
        }

        //长度为8 10 12
        VerifyUtil.verify(t2.getCode().length() != 8 && t2.getCode().length() != 10 && t2.getCode().length() != 12, () -> "编码长度不为固定8,10,12", errorFunc);
        if (t2.getCode().length() != 8 && t2.getCode().length() != 10 && t2.getCode().length() != 12) {
            return;
        }

        VerifyUtil.verify(table.stream().map(ExcelTable2::getCode).filter(StrUtil::isNotEmpty).filter(t2.getCode()::equals).count() > 1, () -> t2.getCode() + "编码重复", errorFunc);
    }
}
